package com.silky.common.utils;

import org.apache.commons.beanutils.PropertyUtils;
import org.yaml.snakeyaml.Yaml;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class YamlConfigUtil {
    private static final Yaml YAML = new Yaml();

    @SuppressWarnings("unchecked")
    public static void loadYamlIntoBean(String path, Object root) throws IOException {
        try {
//            InputStream inputStream1 = YamlConfigUtil.class.getClassLoader().getResourceAsStream(path);
            InputStream inputStream1 = new FileInputStream(path);
            Map<String, Object> yamlMap = YAML.load(inputStream1);
            bindMapToBean(yamlMap, root);
        } catch (Exception e) {
            throw new RuntimeException("Error loading yaml", e);
        }
    }
    public static void loadYamlIntoBeanFromStream(InputStream inputStream1, Object root) throws IOException {
        try {
            Map<String, Object> yamlMap = YAML.load(inputStream1);
            bindMapToBean(yamlMap, root);
        } catch (Exception e) {
            throw new RuntimeException("Error loading yaml", e);
        }
    }
    @SuppressWarnings("unchecked")
    private static void bindMapToBean(Map<String, Object> map, Object root) throws Exception {
        Map<String, Object> properties = new HashMap<>();
        // 递归地将嵌套的Map转换为平面Map
        flattenMap(map, properties, "");
        // 使用Java的InvocationHandler机制来绑定属性到Bean
        Set<String> keys = properties.keySet();
        for (String key : keys) {
            if(key.equals("sourceTaskItemConfig.otherTables")){
                key = key;
            }
            //递归设置属性
            recursionSetBean(key,properties.get(key), root);
        }
    }

    private static void recursionSetBean(String key, Object value, Object root) throws Exception {
        if(key.contains(".")){
            String[] keys = key.split("\\.");
            Object propertyObj ;
            propertyObj = PropertyUtils.getProperty(root, keys[0]);
            if(propertyObj == null){
                Class<?> propertyType = PropertyUtils.getPropertyType(root, keys[0]);
                propertyObj = propertyType.newInstance();
                PropertyUtils.setProperty(root, keys[0], propertyObj);
            }
                String childKey = getNextLevelKey(key);
                recursionSetBean(childKey, value, propertyObj);
       }else{
            if(key.equals("finkDDL")) {
                System.out.println("key:" + key + ",value:" + value);
            }
            if(!(value instanceof List)) {

                PropertyUtils.setProperty(root, key, value);
            }else{
                Object propertyObj ;
                propertyObj = PropertyUtils.getProperty(root, key);
                if(propertyObj == null){
                    Class<?> propertyType = PropertyUtils.getPropertyType(root, key);
                    propertyObj = propertyType.newInstance();
                    PropertyUtils.setProperty(root, key, propertyObj);
                }
                //列表
                List<Map> list = (List) value;
                for (Map map : list) {
                    Object listItemObj = getGenericTypeInstance(key, root);
                    Set<String> keys1 = map.keySet();
                    for (String key1 : keys1) {
                        //递归设置属性
                        recursionSetBean(key1,map.get(key1), listItemObj);
                    }
                    ((List)propertyObj).add(listItemObj);
                }
            }
       }
    }

    /**
     * 构造泛型实例
     * @param key
     * @param root
     * @return
     * @throws NoSuchFieldException
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    private static Object getGenericTypeInstance(String key, Object root) throws NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Field field = root.getClass().getDeclaredField(key);
        Type genericType = field.getGenericType();
        if (genericType instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) genericType;
            Type[] actualTypeArguments = pt.getActualTypeArguments();
            for (Type typeArg : actualTypeArguments) {
                System.out.println("Generic type argument: " + typeArg);
                Class<?> clazz = Class.forName(typeArg.getTypeName());
                Constructor<?> constructor = clazz.getConstructor();
                if (!constructor.isAccessible()) {
                    constructor.setAccessible(true); // 使构造函数可访问
                }
                Object instance = constructor.newInstance();
                System.out.println(instance);
                return instance;
            }
        }
        return null;
    }



    /**
     * 获取下级key 例如:a.b.c=>b.c
     * @param key
     * @return
     */
    private static String getNextLevelKey(String key) {
        int spos;
        if ((spos = key.indexOf(".")) > 0) {
            return key.substring(spos + 1);
        } else {
            return key;
        }
    }

    private static void flattenMap(Map<String, Object> source, Map<String, Object> result, String prefix) {
        for (Map.Entry<String, Object> entry : source.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Map) {
                // 递归处理嵌套的Map
                flattenMap((Map<String, Object>) value, result, prefix + key + ".");
            } else {
                result.put(prefix + key, value);
            }
        }
    }
}
